﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using HttpLib;
using Nette.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using Nette.UserWindow;
using Nette.pojo;
using System.Collections.ObjectModel;

namespace Nette
{
    public partial class MainWindow
    {
        /// <summary>
        /// 默认的请求头
        /// </summary>

        private KVLine ContentTypeLine = new KVLine("Content-Type", "application/json", false, true);
        private OptionWindow optionWindow;

        //public static DependencyProperty UrlHistoryProperty = DependencyProperty.Register("UrlHistory", typeof(List<string>), typeof(MainWindow), new PropertyMetadata(new List<string>()));

        public ObservableCollection<string> UrlHistory = new ObservableCollection<string>();

        //public List<string> UrlHistory {
        //    get => (List<string>)GetValue(UrlHistoryProperty);
        //    set => SetValue(UrlHistoryProperty,value);
        //}

        public MainWindow()
        {

            InitializeComponent();

            //添加默认的kvline
            this.KVBoxHeaders.PutLine(ContentTypeLine);


            MouseDown += delegate
            {
                Keyboard.ClearFocus();
            };

            this.UrlText.ItemsSource = UrlHistory;

        }

        /// <summary>
        /// 初始化操作
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            HistoryEntity? historyEntity = StorageManager.ReadHistory<HistoryEntity>();

            if (historyEntity != null)
            {
                if (historyEntity.urlHistory != null)
                {
                    UrlHistory = historyEntity.urlHistory;
                }
                if (historyEntity.Raw != null)
                {
                    SetRow(historyEntity.Raw);
                }

            }
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            HistoryEntity historyEntity = new HistoryEntity();
            historyEntity.Raw = GetRow();
            historyEntity.urlHistory = UrlHistory;
            StorageManager.WriteHistory(historyEntity);
        }

        public HttpCore currentHttpCore;
        /// <summary>
        /// 获得请求方法
        /// </summary>
        /// <returns></returns>
        public String GetMethod()
        {
            return this.MethodsComboBox.Text;
        }
        public HttpMethod GetMethodEmun()
        {
            return Enum.Parse<HttpMethod>(GetMethod());
        }
        public void SetMethod(string text)
        {
            this.MethodsComboBox.SelectedValuePath = text;
        }

            /// <summary>
            /// 获得请求url
            /// </summary>
         public String GetUrl()
        {
            return this.UrlText.Text;
        }

        /// <summary>
        /// 获得参数
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> GetParams()
        {
            return this.KVBoxParams.getData();
        }

        /// <summary>
        /// 获得请求cookies
        /// </summary>
        /// <returns></returns>
        public CookieCollection GetCookie()
        {
            var dic = this.KVBoxCookies.getData();
            var a = new CookieCollection();
            return a;
        }
        /// <summary>
        /// 获得请求头
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> GetHeader()
        {
            return this.KVBoxHeaders.getData();
        }

        /// <summary>
        /// 获得ContentType
        /// </summary>
        /// <returns></returns>
        public String GetContentType()
        {
            //return ContentTypeLine.ValueStr;
            return (string)((ComboBoxItem)this.ContentTypeComboBox.SelectedValue).Content;
        }
        public void SetContentType(string text)
        {
            //return ContentTypeLine.ValueStr;
            this.ContentTypeComboBox.SelectedValuePath = text;
        }
        /// <summary>
        /// 获得row
        /// </summary>
        /// <returns></returns>

        public void SetRow(string text)
        {
            this.RawDataCtl.Text = text;
        }
        public string GetRow()
        {
            return this.RawDataCtl.Text;
        }
        /// <summary>
        /// 获得encoding
        /// </summary>
        /// <returns></returns>
        private string GetEnCoding()
        {
            return this.EncodingComboBox.Text;
        }
        /// <summary>
        /// 发送请求
        /// </summary>
        public void sendRequest()
        {
            try
            {
                Trace.WriteLine("发送请求");
                Dictionary<string, string> param = GetParams();

                //UrlHistory.Add(GetUrl());
                var url = GetUrl();
                AddUrlHistoryOne(url);

                HttpCore core = currentHttpCore = Http.Core(url, GetMethodEmun());
                if (GetContentType().Equals(HttpContentType.APPLICATION_JSON))
                {
                    core.data(GetRow());
                    this.LoadProgress.Visibility = Visibility.Collapsed;
                }
                else if (GetContentType().Equals(HttpContentType.MULTIPART_FORM_DATA))
                {
                    List<Files>? files = this.FileDataCtl.GetFiles();
                    List<Val>? vals = this.FileDataCtl.GetValues();
                    core.data(files);
                    core.data(vals);
                    this.LoadProgress.Visibility = Visibility.Visible;
                }
                else if (GetContentType().Equals(HttpContentType.APPLICATION_XWWW_FROM_URLENCODED))
                {
                    core.data(GetParams());
                    this.LoadProgress.Visibility = Visibility.Collapsed;
                }
                core.timeout(5000);

                core.encoding(GetEnCoding())
                 .header(GetHeader())
                 .requestProgress((bytesSent, totalBytes) =>
                 {
                     double pro = (bytesSent * 1.0) / (totalBytes * 1.0);
                     //Trace.WriteLine(String.Format("{0}% 上传" , (Math.Round(进度, 2) * 100.0)));
                     this.Dispatcher.Invoke(() =>
                         {
                             this.LoadProgress.Value = pro * 100;
                         });
                 })
                .responseProgress((bytesSent, totalBytes) =>
                {
                    if (totalBytes.HasValue)
                    {
                        double 进度 = (bytesSent * 1.0) / (totalBytes.Value * 1.0);
                        Trace.WriteLine(String.Format("{0}% 下载", (Math.Round(进度, 2) * 100.0)));
                    }
                })
                 .requestBefore((HttpWebResponse response, WebResult web) =>
                 {
                     //发送cookies
                     CookieCollection cookies = response.Cookies;
                     DispatchRequestBefore(response, web);
                     return true;
                 })
                 .fail(DispatchFailResponse)
                 .success(DispatchResponseResult);
            } catch (Exception e)
            {
                DispatchErrorLogger(e);
            }
        }

        public void AddUrlHistoryOne(string url)
        {
            if (String.IsNullOrEmpty(url)) return;
            if (UrlHistory.Count > 6)
            {
                UrlHistory.RemoveAt(UrlHistory.Count - 1);
            }
            if (UrlHistory.Contains(url))
            {
                if (!UrlHistory[0].Equals(url))
                {
                    //放到第一位
                    UrlHistory.Remove(url);
                    UrlHistory.Insert(0, url);
                }
            }
            else
            {
                UrlHistory.Insert(0, url);
            }
            this.UrlText.SelectedIndex = 0;

        }


        public void DispatchResponseResult(WebResult web, string result)
        {
            this.Dispatcher.Invoke(() =>
            {
                ResponseResult(web, result);
            });

        }
        public void ResponseResult(WebResult web, string result)
        {
            #region 响应数据
            if (web == null) return;
            string text = "";
            try
            {
                JObject jObject = JsonConvert.DeserializeObject<JObject>(result);
                if(jObject != null)
                text = jObject.ToString();
                else
                {
                    text = result;
                }
            }
            catch (Exception e)
            {
                text = result;
            }
            Debug.WriteLine(text);
            SetResponseDate(text);

            #endregion

            #region 响应头信息
            if (web.Headers != null)
            {
                SetResponseHeaders(web.Headers);
            }
            #endregion

            #region cookie信息
            if (web.Headers != null)
            {
                string cookie = web.Cookie;
            }
            #endregion
            this.SendFormButton.IsChecked = false;

            #region 状态信息
            List<Val> status = new()
            {
                new Val("地址", web.AbsoluteUri),
                new Val("ip", web.IP),
                new Val("dns", web.DNS),
                new Val("状态", web.StatusCode.ToString()),
                new Val("传输大小", web.OriginalSize.ToString() + "KB")
            };
            this.SetStatusInfo(status);
            #endregion

        }

        public void DispatchRequestBefore(HttpWebResponse response, WebResult web)
        {
            this.Dispatcher.Invoke(() =>
            {
                RequestBefore(web);
            });
        }
        public void RequestBefore(WebResult web)
        {
            #region 请求头
            //SetRequestHeaders(web.Headers);
            #endregion

            #region 请求数据

            #endregion
        }
        public void DispatchFailResponse(WebResult web, Exception e)
        {
            Dispatcher.Invoke(() =>
            {
                FailResponse(web, e);
            });
        }
        public void FailResponse(WebResult web, Exception e)
        {
            ResponseResult(web,"");
            this.TabControl_Request.SelectedItem = this.TabItem_Status;
        }

        public void DispatchErrorLogger(Exception e) 
        {
            this.Dispatcher.Invoke(() =>
            {
                ErrorLogger(e);

            });
        }
        public void ErrorLogger(Exception e)
        {
            this.SetErrorLog(e.GetType() +"\n"+ e.Message);
            this.SendFormButton.IsChecked = false;
            this.TabControl_Request.SelectedItem = this.TabItem_Error;

           
        }

        public void SetResponseDate(String str)
        {
            this.ResponseMsgCtl.Text = str;
        }

        public void SetResponseHeaders(List<Val> headers)
        {

            this.ResponseHeaderCtl.ItemsSource = headers;
        }
        public void SetRequestHeaders(IEnumerable headers)
        {

            this.RequestHeaderCtl.ItemsSource = headers;
        }
        public void SetResponseCookies(List<Val> cookies)
        {

            this.ResponseCookieCtrl.ItemsSource = cookies;
        }
        public void SetResponseData(List<Val> cookies)
        {
            this.ResponseCookieCtrl.ItemsSource = cookies;
        }

        public void SetErrorLog(string message)
        {
            this.ErrorLoggerCtl.Text = message;
        }

        public void SetStatusInfo(IEnumerable vs) {
            this.StatusInfoCtrl.ItemsSource = vs;
        }
        public void UpdateContentType()
        {
            string contentType = (string)((ComboBoxItem)this.ContentTypeComboBox.SelectedValue).Content;
            this.ContentTypeLine.ValueStr = contentType;

            if (contentType.Equals(HttpContentType.APPLICATION_JSON))
            {
                this.TabeItem_Params.IsEnabled = false;
                this.TabeItem_Body.IsEnabled = false;
                this.TabeItem_Raw.IsEnabled = true;
            }
            else if (contentType.Equals(HttpContentType.MULTIPART_FORM_DATA))
            {
                this.TabeItem_Body.IsEnabled = true;
                this.TabeItem_Params.IsEnabled = false;
                this.TabeItem_Raw.IsEnabled = false;
            } else if(contentType.Equals(HttpContentType.APPLICATION_XWWW_FROM_URLENCODED))
            {
                this.TabeItem_Params.IsEnabled = true;
                this.TabeItem_Body.IsEnabled = false;
                this.TabeItem_Raw.IsEnabled = false;
            }
        }
        private void SendFormButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            e.Handled = true;
        }

        private void SendFormButton_Checked(object sender, System.Windows.RoutedEventArgs e)
        {
            sendRequest();
            e.Handled = true;
        }
        private void ContentTypeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IsInitialized)
            {
                UpdateContentType();
            }
        }
        /// <summary>
        /// 初始化完成执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Initialized(object sender, EventArgs e)
        {
            UpdateContentType();
        }

        private void SendFormButton_Unchecked(object sender, RoutedEventArgs e)
        {
            e.Handled = false;
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (this.MenuItem_Setting.Equals(sender))
            {
                OpenOptionWindow();
            }
            else if (this.MenuItem_Topmost.Equals(sender)) 
            {
                this.Topmost = !this.Topmost;
                if (this.Topmost == true) {
                    this.MenuItem_Topmost.Header = "取消置顶";
                }
                else
                {
                    this.MenuItem_Topmost.Header = "取消置顶";
                }
            }
        }

        public void OpenOptionWindow()
        {
            optionWindow = new OptionWindow();
            optionWindow.ShowDialog();
        }
    }
}
